package com.fast.pay.trade.service.impl;

import java.math.BigDecimal;
import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;

import com.fast.pay.account.dao.RpSettRecordDao;
import com.fast.pay.account.entity.RpAccount;
import com.fast.pay.account.entity.RpSettRecord;
import com.fast.pay.account.enums.SettModeTypeEnum;
import com.fast.pay.account.enums.SettRecordStatusEnum;
import com.fast.pay.account.service.RpAccountQueryService;
import com.fast.pay.account.service.RpAccountTransactionService;
import com.fast.pay.common.core.exception.BizException;
import com.fast.pay.trade.exception.TradeBizException;
import com.fast.pay.trade.service.RpRemitManagerService;
import com.fast.pay.user.entity.RpUserInfo;
import com.fast.pay.user.entity.RpUserPayConfig;
import com.fast.pay.user.exception.UserBizException;
import com.fast.pay.user.service.RpUserInfoService;
import com.fast.remote.channel.api.ChannelPayApi;
import com.fast.remote.channel.api.ChannelRemitApi;

/**
 *  代付订单处理
 */
@Service("rpRemitManagerService")
public class RpRemitManagerServiceImpl implements RpRemitManagerService{
	
	@Autowired
	private RpSettRecordDao rpSettRecordDao;
	
    @Autowired
    private RpUserInfoService rpUserInfoService;

    
    @Autowired
	private RpAccountTransactionService rpAccountTransactionService;
    
    
    @Autowired
	private RpAccountQueryService rpAccountQueryService;

	
	
	/**
     * 初始化直连扫码支付数据,直连扫码支付初始化方法规则 1:根据(商户编号 + 商户订单号)确定订单是否存在
     * 1.1:如果订单存在,抛异常,提示订单已存在 1.2:如果订单不存在,创建支付订单 2:创建支付记录 3:根据相应渠道方法
     * 4:调转到相应支付渠道扫码界面
     *
     * @param payKey      商户支付KEY
     * @param productName 产品名称
     * @param orderNo     商户订单号
     * @param orderDate   下单日期
     * @param orderTime   下单时间
     * @param orderPrice  订单金额(元)
     * @param payWayCode  支付方式编码
     * @param orderIp     下单IP
     * @param orderPeriod 订单有效期(分钟)
     * @param returnUrl   支付结果页面通知地址
     * @param notifyUrl   支付结果后台通知地址
     * @param remark      支付备注
     * @param field1      扩展字段1
     * @param field2      扩展字段2
     * @param field3      扩展字段3
     * @param field4      扩展字段4
     * @param field5      扩展字段5
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void initRemitPay(RpUserPayConfig rpUserPayConfig, String orderNo, BigDecimal orderAmount, String orderIp, String bankAccountName, String banAccountNo, String remark, String field1, String field2, String field3) {

        //判断商户
        String merchantNo = rpUserPayConfig.getUserNo();// 商户编号
        RpUserInfo rpUserInfo = rpUserInfoService.getDataByMerchentNo(merchantNo);
        if (rpUserInfo == null) {
            throw new UserBizException(UserBizException.USER_IS_NULL, "用户不存在");
        }
        
        if (orderAmount == null || orderAmount.compareTo(new BigDecimal(1)) == -1) {
        	throw new BizException("单比结算金额不能低于1元");
        }
        
        //判断账户
        RpAccount account = rpAccountQueryService.getAccountByUserNo(merchantNo);
		BigDecimal availableBalance = account.getAvailableBalance();
		if (availableBalance.compareTo(orderAmount) == -1) {
			throw new BizException("账户余额不足");
		}
       
        RpSettRecord rpSettRecord = rpSettRecordDao.getRecordByMerchantNoAndOrderNo(merchantNo, orderNo);
        if (rpSettRecord == null) {
        	rpSettRecord = getRpSettRecord(orderNo,merchantNo, rpUserInfo.getUserName(), account.getAccountNo(), orderAmount,rpUserPayConfig.getChannelCode(), "代付", new BigDecimal(rpUserPayConfig.getRateValue()), orderIp, bankAccountName, banAccountNo, remark,  field1, field2, field3);
        	rpSettRecordDao.insert(rpSettRecord);
        } else {
                throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "订单已存在！");
        }
        
        // 冻结准备结算出去的资金
        rpAccountTransactionService.freezeAmount(merchantNo, orderAmount);
    }
    
    
    @Override
	public RpSettRecord getPayResult(String merchantNo, String orderNo) {
        RpSettRecord rpSettRecord = rpSettRecordDao.getRecordByMerchantNoAndOrderNo(merchantNo, orderNo);
		if(rpSettRecord==null) {
            throw new TradeBizException(TradeBizException.TRADE_ORDER_ERROR, "订单已存在！");
		}
        return rpSettRecord;
	}





	@Transactional(rollbackFor = Exception.class)
	private RpSettRecord getRpSettRecord(String orderNo,String merchantNo, String userName, String accountNo, BigDecimal settAmount,String payWayCode,String payWayName,BigDecimal fee,String orderIp, String bankAccountName,String banAccountNo,String remark,String field1, String field2, String field3) {
		// 所行查询账户
		RpSettRecord settRecord = new RpSettRecord();
		settRecord.setSettFee(fee);// 
		settRecord.setAccountNo(accountNo);
		settRecord.setCountry("中国");
//		settRecord.setProvince(rpRemitParam.getProvince());
//		settRecord.setCity(rpRemitParam.getCity());
//		settRecord.setAreas(rpRemitParam.getAreas());
//		settRecord.setBankAccountAddress(rpRemitParam.getStreet());
		settRecord.setBankAccountName(bankAccountName);
//		settRecord.setBankCode(rpRemitParam.getBankCode());
//		settRecord.setBankName(rpRemitParam.getBankName());
		settRecord.setBankAccountNo(banAccountNo);
		settRecord.setBankAccountType("PUBLIC_ACCOUNT");
		//settRecord.setOperatorLoginname("");
		//settRecord.setOperatorRealname("");
		settRecord.setRemitAmount(settAmount);
		settRecord.setRemitRequestTime(new Date());
		settRecord.setSettAmount(settAmount);
		settRecord.setSettMode(SettModeTypeEnum.REGULAR_SETTLE.toString());
		settRecord.setSettStatus(SettRecordStatusEnum.WAIT_CONFIRM.name());
		settRecord.setUserName(userName);
		settRecord.setUserNo(merchantNo);
		//settRecord.setMobileNo(rpRemitParam.getMobileNo());
		settRecord.setEditTime(new Date());
		settRecord.setOrderNo(orderNo);
		//settRecord.setTrxNo(trxNo);
		settRecord.setPayWayCode(payWayCode);
		settRecord.setPayWayName(payWayName);
		settRecord.setRemark(remark);
		settRecord.setField1(field1);
		settRecord.setField2(field2);
		settRecord.setField3(field3);
		return settRecord;
	}


	
	@Override
	public ChannelRemitApi getChennelBean(String channelCode) {
		//获得支付通道
        WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
        ChannelRemitApi bean = null;
        try {
            bean = (ChannelRemitApi)wac.getBean(channelCode);
		} catch (Exception e) {
			throw new UserBizException(UserBizException.USER_PAY_CONFIG_ERRPR, "获得用户支付通道接口失败");
		}
        if(bean==null) {
        	throw new UserBizException(UserBizException.USER_PAY_CONFIG_ERRPR, "用户支付通道未部署");
        }
		return bean;
	}
	
}
